package org.zcode.generator.core.generator.method;

import org.mybatis.generator.api.IntrospectedTable;
import org.mybatis.generator.api.dom.java.FullyQualifiedJavaType;
import org.mybatis.generator.api.dom.java.JavaVisibility;
import org.mybatis.generator.api.dom.java.Method;
import org.mybatis.generator.api.dom.java.Parameter;
import org.zcode.generator.core.bean.CreateApiServiceIPo;
import org.zcode.generator.core.generator.MethodCreator;
import org.zcode.generator.core.generator.clazz.DesignSystemCreator;
import org.zcode.generator.core.util.GeneratorUtil;
import org.zcode.generator.core.config.BeanTypeConfig;
import org.zcode.generator.core.config.XmlConfig;

/**
 * @Description:
 * @author zhoulk
 * @date: 2019/10/15
 */
public class AtomMethodCreator implements MethodCreator {
    private FullyQualifiedJavaType qryOPoType;
    private String tableRemarks;
    private String servicePack;
    private String author;
    private FullyQualifiedJavaType interfaceType;
    private FullyQualifiedJavaType qrysIPoType;
    private FullyQualifiedJavaType pojoConditionType;
    private FullyQualifiedJavaType qrysOPoType;
    private FullyQualifiedJavaType updIPoType;
    private FullyQualifiedJavaType pojoType;
    private FullyQualifiedJavaType addIPoType;
    private IntrospectedTable introspectedTable;
    private XmlConfig xmlConfig;

    public AtomMethodCreator(XmlConfig xmlConfig,
                             BeanTypeConfig beanConfig,
                             IntrospectedTable introspectedTable) {
        this.tableRemarks = GeneratorUtil.getTableRemarks(introspectedTable.getRemarks());
        this.xmlConfig = xmlConfig;
        this.author = xmlConfig.author;
        this.servicePack = xmlConfig.servicePack;
        this.qryOPoType = beanConfig.qryOPoType;
        this.interfaceType = beanConfig.interfaceType;
        this.qrysIPoType = beanConfig.qrysIPoType;
        this.pojoConditionType = beanConfig.pojoConditionType;
        this.qrysOPoType = beanConfig.qrysOPoType;
        this.updIPoType = beanConfig.updIPoType;
        this.pojoType = beanConfig.pojoType;
        this.addIPoType = beanConfig.addIPoType;
        this.introspectedTable = introspectedTable;
    }

    @Override
    public Method qryByIdMethod(String tableName, int flag) {
        if (introspectedTable.getPrimaryKeyColumns() == null || introspectedTable.getPrimaryKeyColumns().size() == 0) {
            return null;
        }
        Method method = new Method();
        method.setName("qry" + tableName);
        method.setReturnType(qryOPoType);
        Parameter parameter = new Parameter(new FullyQualifiedJavaType("Long"),
                introspectedTable.getPrimaryKeyColumns().get(0).getJavaProperty());
        parameter.addAnnotation("@PathVariable");
        try {
            method.addParameter(parameter);
        } catch (Exception e) {
            return null;
        }
        if (flag == 1) {
            String url = "/qry" + tableName;
            String apiName = tableRemarks + "根据主键查询接口";
            method.addAnnotation("@RequestMapping(value = \"" + url + "/{" + introspectedTable.getPrimaryKeyColumns().get(0).getJavaProperty() + "}\", method = RequestMethod.GET)");
            method.addAnnotation("@ApiOperation(value = \"I" + tableName + "ApiService.qry" + tableName + "\", notes = \"" + apiName + " - " + author + "\")");
            method.addJavaDocLine(GeneratorUtil.getDocTmpl(servicePack + ".I" + tableName + "ApiService.qry" + tableName + "ById",
                    method.getParameters().get(0).getName(), qryOPoType.getShortName(),
                    "根据主键查询", author));
            if (xmlConfig.apiSys) {
                createApiService(apiName, tableName, url, introspectedTable.getTableConfiguration().getTableName());
            }
        }
        if (flag == 0) {
            method.setVisibility(JavaVisibility.PUBLIC);
        }
        StringBuilder sb = new StringBuilder();
        sb.append("return ");
        sb.append("BeanConvertor.convertBean(");
        sb.append(GeneratorUtil.toLowerCase(interfaceType.getShortName())).append(".");
        sb.append("qry").append(tableName).append("ById");
        sb.append("(");
        sb.append(introspectedTable.getPrimaryKeyColumns().get(0).getJavaProperty());
        sb.append("), Qry").append(tableName).append("OPo.class);");
        method.addBodyLine(sb.toString());
        return method;
    }

    /**
     * 添加数量统计方法
     */
    public Method countMethod(String tableName, int flag) {
        Method method = new Method();
        method.setName("count" + tableName);
        method.setReturnType(FullyQualifiedJavaType.getIntInstance());
        Parameter parameter = new Parameter(qrysIPoType, "inParam");
        parameter.addAnnotation("@RequestBody");
        method.addParameter(parameter);
        if (flag == 1) {
            String url = "/count" + tableName;
            String apiName = tableRemarks + "数量统计接口";
            method.addAnnotation("@RequestMapping(value = \"" + url + "\", method = RequestMethod.GET)");
            method.addAnnotation("@ApiOperation(value = \"I" + tableName + "ApiService.count" + tableName + "\", notes = \"" + apiName + " - " + author + "\")");
            method.addJavaDocLine(
                    GeneratorUtil.getDocTmpl(servicePack + ".I" + tableName + "Service.count" + tableName,
                            method.getParameters().get(0).getName(),
                            FullyQualifiedJavaType.getIntInstance().getShortName(),
                            "统计条数", author));
        }
        if (flag == 0) {
            method.setVisibility(JavaVisibility.PUBLIC);
        }

        StringBuilder sb = new StringBuilder();
        sb.append(pojoConditionType.getShortName()).append(" condition = BeanConvertor.convertBean(inParam, ").append(pojoConditionType.getShortName()).append(".class);");
        method.addBodyLine(sb.toString());
        sb.setLength(0);
        sb.append("return ");
        sb.append(GeneratorUtil.toLowerCase(interfaceType.getShortName())).append(".count").append(tableName);
        sb.append("(");
        sb.append("condition");
        sb.append(");");
        method.addBodyLine(sb.toString());
//		method.addBodyLine("logger.debug(\"count: {}\", count);");
//		method.addBodyLine("return count;");
        return method;
    }

    /**
     * 列表查询接口
     */
    public Method qrysMethod(String tableName, int flag) {
        Method method = new Method();
        method.setName("qry" + tableName + "s");
        method.setReturnType(new FullyQualifiedJavaType("List<" + qrysOPoType.getShortName() + ">"));
        Parameter parameter = new Parameter(qrysIPoType, "inParam");
        parameter.addAnnotation("@RequestBody");
        method.addParameter(parameter);
        if (flag == 1) {
            method.addAnnotation("@RequestMapping(value = \"/qry" + tableName + "s\", method = RequestMethod.GET)");
            method.addAnnotation("@ApiOperation(value = \"I" + tableName + "ApiService.qry" + tableName + "s\", notes = \"" + tableRemarks + "列表查询接口 - " + author + "\")");
            method.addJavaDocLine(
                    GeneratorUtil.getDocTmpl(servicePack + ".I" + tableName + "Service.qry" + tableName + "s",
                            method.getParameters().get(0).getName(),
                            new FullyQualifiedJavaType("List<" + qrysOPoType.getShortName() + ">").getShortName(),
                            "查询列表", author));
        }
        if (flag == 0) {
            method.setVisibility(JavaVisibility.PUBLIC);
        }

        StringBuilder sb = new StringBuilder();
        sb.append(pojoConditionType.getShortName()).append(" condition = BeanConvertor.convertBean(inParam, ").append(pojoConditionType.getShortName()).append(".class);");
        method.addBodyLine(sb.toString());
        sb.setLength(0);
        sb.append("return ");
        sb.append("BeanConvertor.convertBeanList(");
        sb.append(GeneratorUtil.toLowerCase(interfaceType.getShortName())).append(".qry").append(tableName).append("s");
        sb.append("(");
        sb.append("condition");
        sb.append("), ").append(qrysOPoType.getShortName()).append(".class);");
        method.addBodyLine(sb.toString());
//		method.addBodyLine("logger.debug(\"count: {}\", count);");
//		method.addBodyLine("return count;");
        return method;
    }

    /**
     * 更新接口
     * @param tableName
     * @param flag
     * @return
     */
    public Method updMethod(String tableName, int flag) {
        Method method = new Method();
        method.setName("upd" + tableName);
        method.setReturnType(new FullyQualifiedJavaType("void"));
        Parameter parameter = new Parameter(updIPoType, "inParam");
        parameter.addAnnotation("@RequestBody");
        method.addParameter(parameter);
        if (flag == 1) {
            method.addAnnotation("@RequestMapping(value = \"/upd" + tableName + "\", method = RequestMethod.PUT)");
            method.addAnnotation("@ApiOperation(value = \"I" + tableName + "ApiService.upd" + tableName + "\", notes = \"" + tableRemarks + "根据主键更新接口 - " + author + "\")");
            method.addJavaDocLine(
                    GeneratorUtil.getDocTmpl(servicePack + ".I" + tableName + "Service.upd" + tableName + "ById",
                            method.getParameters().get(0).getName(),
                            "",
                            "根据ID更新", author));
        }
        if (flag == 0) {
            method.setVisibility(JavaVisibility.PUBLIC);
        }

        StringBuilder sb = new StringBuilder();
        sb.append(pojoType.getShortName()).append(" ").append(GeneratorUtil.toLowerCase(pojoType.getShortName())).append(" = BeanConvertor.convertBean(inParam, ").append(pojoType.getShortName()).append(".class);");
        method.addBodyLine(sb.toString());
        sb.setLength(0);
        sb.append(GeneratorUtil.toLowerCase(interfaceType.getShortName())).append(".upd").append(tableName).append("ById");
        sb.append("(");
        sb.append(GeneratorUtil.toLowerCase(pojoType.getShortName()));
        sb.append(");");
        method.addBodyLine(sb.toString());
//		method.addBodyLine("logger.debug(\"count: {}\", count);");
//		method.addBodyLine("return count;");
        return method;
    }

    /**
     * 新增接口
     */
    public Method addMethod(String tableName, int flag) {
        Method method = new Method();
        method.setName("add" + tableName);
        method.setReturnType(new FullyQualifiedJavaType("void"));
        Parameter parameter = new Parameter(addIPoType, "inParam");
        parameter.addAnnotation("@RequestBody");
        method.addParameter(parameter);
        if (flag == 1) {
            String url = "add" + tableName;
            String apiName = tableRemarks + "新增接口";
            method.addAnnotation("@RequestMapping(value = \"" + url + "\", method = RequestMethod.POST)");
            method.addAnnotation("@ApiOperation(value = \"I" + tableName + "ApiService.upd" + tableName + "\", notes = \"" + apiName + " - " + author + "\")");
            method.addJavaDocLine(GeneratorUtil.getDocTmpl(servicePack + ".I" + tableName + "Service.add" + tableName + "", method.getParameters().get(0).getName(), "", apiName, author));
        }
        if (flag == 0) {
            method.setVisibility(JavaVisibility.PUBLIC);
        }

        StringBuilder sb = new StringBuilder();
        sb.append(pojoType.getShortName()).append(" ").append(GeneratorUtil.toLowerCase(pojoType.getShortName())).append(" = BeanConvertor.convertBean(inParam, ").append(pojoType.getShortName()).append(".class);");
        method.addBodyLine(sb.toString());
        sb.setLength(0);
        sb.append(GeneratorUtil.toLowerCase(interfaceType.getShortName())).append(".add").append(tableName);
        sb.append("(");
        sb.append(GeneratorUtil.toLowerCase(pojoType.getShortName()));
        sb.append(");");
        method.addBodyLine(sb.toString());
//		method.addBodyLine("logger.debug(\"count: {}\", count);");
//		method.addBodyLine("return count;");
        return method;
    }

    public void createApiService(String apiName, String tableName, String url, String table) {
        CreateApiServiceIPo iPo = new CreateApiServiceIPo();
        iPo.setServiceCode("201");
        iPo.setApiName(apiName);
        iPo.setApiType(2);
        iPo.setCreateOpname(author);
        iPo.setTaskCode("R100009");
        iPo.setReqType("HTTP");
        iPo.setReqMode("GET");
        iPo.setReqAddr("http://ip:port/" + "dms/" + GeneratorUtil.toLowerCase(tableName) + url);
        iPo.setMsgType("JSON");
        iPo.setDataTableName(table);
        iPo.setApiDes(apiName);
        DesignSystemCreator.createApi(iPo);
    }
}
